package com.meatball.dronefly;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.maps.MapsInitializer;
import com.meatball.dronefly.camera.CameraGimbalActivity;
import com.meatball.dronefly.fly.FlyActivity;
import com.meatball.dronefly.service.WebSocketClientService;
import com.meatball.dronefly.utils.MWebSocketClient;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import dji.common.error.DJIError;
import dji.common.error.DJISDKError;
import dji.common.realname.AircraftBindingState;
import dji.common.realname.AppActivationState;
import dji.common.useraccount.UserAccountState;
import dji.common.util.CommonCallbacks;
import dji.sdk.base.BaseComponent;
import dji.sdk.base.BaseProduct;
import dji.sdk.realname.AppActivationManager;
import dji.sdk.sdkmanager.DJISDKInitEvent;
import dji.sdk.sdkmanager.DJISDKManager;
import dji.sdk.useraccount.UserAccountManager;

/**
 * 主类
 * @author 张翔宇
 * @since 2022年8月30日
 */
public class MainActivity extends AppCompatActivity {
    /**
     * 显示应用程序激活状态的文本试图
     */
    private TextView tvAppActivation;

    /**
     * 显示无人机绑定状态的文本视图
     */
    private TextView tvAircraftBinding;

    /**
     * 应用程序激活状态监听器
     */
    private AppActivationState.AppActivationStateListener activationStateListener;

    /**
     * 无人机绑定状态监听
     */
    private AircraftBindingState.AircraftBindingStateListener bindingStateListener;

    /**
     * 需要申请的用户权限
     */
    private static final String[] PERMISSION_LIST = new String[]{
            Manifest.permission.BLUETOOTH,
            Manifest.permission.BLUETOOTH_ADMIN,
            Manifest.permission.VIBRATE,
            Manifest.permission.INTERNET,
            Manifest.permission.ACCESS_WIFI_STATE,
            Manifest.permission.ACCESS_COARSE_LOCATION,
            Manifest.permission.ACCESS_NETWORK_STATE,
            Manifest.permission.ACCESS_FINE_LOCATION,
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.READ_PHONE_STATE,
    };

    /**
     * 缺失的用户权限
     */
    private List<String> missingPermission = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 检查应用程序权限
        if (!checkPermissions()) {
            // 存在缺失权限，调用requestPermission申请应用程序权限
            requestPermission();
        }
        // 再次检查应用程序权限
        if (checkPermissions()) {
            // 不存在权限缺失，开始注册应用程序
            registerApplication();
        }
        // 初始化监听器
        initListener();
        // 初始化UI
        initUI();
        // 高德地图授权
        privacyCompliance();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 移除应用程序激活监听
        AppActivationManager.getInstance().removeAppActivationStateListener(activationStateListener);
        // 移除无人机绑定监听
        AppActivationManager.getInstance().removeAircraftBindingStateListener(bindingStateListener);
    }

    /**
     * 检查应用程序权限
     * @return true/false
     */
    private boolean checkPermissions() {
        // 判断应用程序的SDK版本是否大于22(Android 5.1)，低于该版本时不需要申请权限
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 遍历所有Mobile SDK需要的权限
            for (String permission : PERMISSION_LIST) {
                // 判断该权限是否已经被赋予
                if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
                    missingPermission.add(permission);
                }
            }
            // 如果存在缺失权限，则返回true，否则返回false
            return missingPermission.isEmpty();
        } else {
            return true;
        }
    }

    /**
     * 申请应用程序权限
     */
    private void requestPermission() {
        ActivityCompat.requestPermissions(
                this,
                missingPermission.toArray(new String[missingPermission.size()]),
                1009);
    }

    /**
     * 注册应用程序
     */
    private void registerApplication() {
        AsyncTask.execute(() -> DJISDKManager.getInstance().registerApp(MainActivity.this.getApplicationContext(),
                new DJISDKManager.SDKManagerCallback() {
            /**
             *  注册应用程序回调方法
             * @param djiError 通过djiError变量回调注册信息。当djiError对象为空时，则说明注册成功；
             *                 当djiError对象不为空时，该对象包含了注册错误的相关说明。
             */
            @Override
            public void onRegister(DJIError djiError) {
                if (djiError == DJISDKError.REGISTRATION_SUCCESS) {
                    showToast("应用程序注册成功。" + djiError.getDescription());
                    DJISDKManager.getInstance().startConnectionToProduct();
                } else {
                    showToast("应用程序注册失败。" + djiError.getDescription());
                }
            }

            /**
             * 无人机失去连接回调方法
             * 当移动设备与无人机断开连接时回调该函数。注意，此处的无人机失去连接不是指无人机
             * 与遥控器之间的信号丢失，而是指移动设备与遥控器断开连接
             */
            @Override
            public void onProductDisconnect() {
                showToast("设备断开连接。");
            }

            /**
             * 无人机连接回调方法
             * @param baseProduct 连接的大疆产品对象
             */
            @Override
            public void onProductConnect(BaseProduct baseProduct) {
                if (baseProduct.getModel() != null) {
                    showToast("设备已连接：" + baseProduct.getModel().getDisplayName());
                }
            }

            /**
             * 无人机连接变化回调方法
             * 当移动设备所连接的无人机发生变化时回调
             * @param baseProduct 变化后的无人机对象
             */
            @Override
            public void onProductChanged(BaseProduct baseProduct) {

            }

            /**
             * 无人机组件变化回调方法
             * 组件键用于声明组件类型，为枚举类型变量，包括相机（CAMERA）、云台（GIMBAL）、
             * 飞行控制器（FLIGHTCONTROLLER）等类型
             * @param componentKey 组件键
             * @param oldComponent 变化前组件对象
             * @param newComponent 变化后组件对象
             */
            @Override
            public void onComponentChange(BaseProduct.ComponentKey componentKey, BaseComponent oldComponent, BaseComponent newComponent) {

            }

            /**
             * 初始化进程回调方法
             * 在注册应用程序时实际上也在进行Mobile SDK的初始化，包括资源初始化、限飞数据库初始化等
             * @param djisdkInitEvent 初始化状态获取
             * @param process 初始化进度，其值域为[0,100]
             */
            @Override
            public void onInitProcess(DJISDKInitEvent djisdkInitEvent, int process) {
                showToast(djisdkInitEvent.getInitializationState().toString() + "进度" + process + "%");
            }

            /**
             * 限飞数据库下载进度回调方法
             * @param process 进度
             * @param sum 总和
             */
            @Override
            public void onDatabaseDownloadProgress(long process, long sum) {
                Log.v("限飞数据库下载", "已下载" + process + "字节，总共：" + sum + "字节" );
            }
        }));
    }

    /**
     * 初始化登录
     */
    private void initUI() {
        // 获取[登录]按钮实例对象
        Button btnLogin = findViewById(R.id.btn_login);
        // 为[登录]按钮增加监听
        btnLogin.setOnClickListener(view -> {
            UserAccountManager.getInstance().logIntoDJIUserAccount(MainActivity.this,
                    new CommonCallbacks.CompletionCallbackWith<UserAccountState>() {
                        @Override
                        public void onSuccess(UserAccountState userAccountState) {
                            showToast("登录成功。");
                        }

                        @Override
                        public void onFailure(DJIError djiError) {
                            showToast("登录失败：" + djiError.getDescription());
                        }
                    });
        });

        // 获取【退出】按钮实例对象
        Button btnLogout = findViewById(R.id.btn_logout);
        // 为【退出】增加监听
        btnLogout.setOnClickListener(view -> {
            UserAccountManager.getInstance().logoutOfDJIUserAccount(djiError -> {
                if (djiError == null) {
                    showToast("退出成功。");
                } else {
                    showToast("退出失败：" + djiError.getDescription());
                }
            });
        });

        // 获取【激活状态】按钮实例对象
        Button btnAppActivationStatus = findViewById(R.id.btn_status_app_activation);
        // 为【激活状态】增加监听
        btnAppActivationStatus.setOnClickListener(view -> {
            AppActivationManager manager = DJISDKManager.getInstance().getAppActivationManager();
            showToast("激活状态：" + manager.getAppActivationState());
        });

        // 获取【绑定状态】按钮实例对象
        Button btnAircraftBindingStatus = findViewById(R.id.btn_status_aircraft_binding);
        // 为【绑定状态】按钮增加监听
        btnAircraftBindingStatus.setOnClickListener(view -> {
            AppActivationManager manager = DJISDKManager.getInstance().getAppActivationManager();
            showToast("绑定状态：" + manager.getAircraftBindingState());
            // 当无人机绑定状态为UNBOUND或者UNBOUND_BUT_CANNOT_SYNC时，
            // 开发者需要引导用户跳转到DJI GO或DJI GO 4软件进行无人机绑定
            if (manager.getAircraftBindingState().equals(AircraftBindingState.UNBOUND) ||
                    manager.getAircraftBindingState().equals(AircraftBindingState.UNBOUND_BUT_CANNOT_SYNC)) {
                Intent launchIntent = getPackageManager().getLaunchIntentForPackage("dji.go.v4");
                if (Objects.nonNull(launchIntent)) {
                    startActivity(launchIntent);
                } else {
                    showToast("未安装DJI Go 4。");
                }
            }
        });

        // 飞行页面
        Button btnFly = findViewById(R.id.btn_fly);
        btnFly.setOnClickListener(view -> {
            Intent intent = new Intent(MainActivity.this, FlyActivity.class);
            startActivity(intent);
            // if (checkDroneConnection()) {
            //     Intent intent = new Intent(MainActivity.this, FlightActivity.class);
            //     startActivity(intent);
            // }
        });

        // 获得【飞行控制器】按钮实例对象
        Button btnFlightController = findViewById(R.id.btn_flight_unit_controller);
        // 对【飞行控制器】按钮增加监听
        btnFlightController.setOnClickListener(view -> {
            // 弹出FlightActive
            Intent i = new Intent(MainActivity.this, FlightActivity.class);
            startActivity(i);
           // if (checkDroneConnection()) {
           //     // 弹出FlightActive
           //     Intent i = new Intent(MainActivity.this, FlightActivity.class);
           //     startActivity(i);
           // }
        });

        // 获取【在地图中显示无人机位置(高德地图)】按钮的实例对象
        Button btnGaoDeMap = findViewById(R.id.btn_map_gao_de);
        btnGaoDeMap.setOnClickListener(view -> {
            // 弹出MapGaoDeActivity
            Intent i = new Intent(MainActivity.this, MapGaoDeActivity.class);
            startActivity(i);
            // if (checkDroneConnection()) {
            //     Intent i = new Intent(MainActivity.this, MapGaoDeActivity.class);
            //     startActivity(i);
            // }
        });
        // 应用程序激活状态文本视图
        tvAppActivation = findViewById(R.id.tv_status_app_activation);
        // 无人机绑定状态文本视图
        tvAircraftBinding = findViewById(R.id.tv_status_aircraft_binding);

        // 获取实时图传按钮
        Button btnCameraGimbal = findViewById(R.id.btn_camera_gimbal);
        btnCameraGimbal.setOnClickListener(view -> {
            // 弹出MapGaoDeActivity
//            Intent i = new Intent(MainActivity.this, CameraGimbalActivity.class);
//            startActivity(i);
             if (checkDroneConnection()) {
                 Intent i = new Intent(MainActivity.this, CameraGimbalActivity.class);
                 startActivity(i);
             }
        });
    }

    /**
     * 初始化监听器
     */
    private void initListener() {
        // 对回调的应用程序激活状态对象进行操作
        activationStateListener = state -> runOnUiThread(() -> tvAppActivation
                .setText(String.format(getString(R.string.tv_status_app_activation_1), state.name())));

        // 对回调的无人机绑定状态进行操作
        bindingStateListener = state -> runOnUiThread(() -> tvAircraftBinding
                .setText(String.format(getString(R.string.tv_status_aircraft_binding_1), state.name())));

        // 添加应用程序激活监听器
        AppActivationManager.getInstance().addAppActivationStateListener(activationStateListener);

        // 添加无人机绑定监听器
        AppActivationManager.getInstance().addAircraftBindingStateListener(bindingStateListener);
    }

    /**
     * 判断应用程序注册、激活、无人机绑定及连接等是否正常
     * @return true/false
     */
    private boolean checkDroneConnection() {
        // 应用程序激活管理器
        AppActivationManager manager = DJISDKManager.getInstance().getAppActivationManager();

        // 判断应用程序是否注册
        if (!DJISDKManager.getInstance().hasSDKRegistered()) {
            showToast("应用程序未注册。");
            return false;
        }

        // 判断应用程序是否激活
        if (manager.getAppActivationState() != AppActivationState.ACTIVATED) {
            showToast("应用程序未激活。");
            return false;
        }

        // 判断无人机是否绑定
        // if (manager.getAircraftBindingState() != AircraftBindingState.BOUND) {
        //     showToast("无人机未绑定。");
        //     return false;
        // }

        // 判断无人机是否连接正常
        BaseProduct product = DJISDKManager.getInstance().getProduct();
        if (product == null || !product.isConnected()) {
            showToast("无人机连接失败。");
            return false;
        }
        return true;
    }

    private void privacyCompliance() {
        MapsInitializer.updatePrivacyShow(MainActivity.this,true,true);
        MapsInitializer.updatePrivacyAgree(MainActivity.this,true);
        // SpannableStringBuilder spannable = new SpannableStringBuilder("\"亲，感谢您对XXX一直以来的信任！我们依据最新的监管要求更新了XXX《隐私权政策》，特向您说明如下\n1.为向您提供交易相关基本功能，我们会收集、使用必要的信息；\n2.基于您的明示授权，我们可能会获取您的位置（为您提供附近的商品、店铺及优惠资讯等）等信息，您有权拒绝或取消授权；\n3.我们会采取业界先进的安全措施保护您的信息安全；\n4.未经您同意，我们不会从第三方处获取、共享或向提供您的信息；\n");
        // spannable.setSpan(new ForegroundColorSpan(Color.BLUE), 35, 42, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        // new AlertDialog.Builder(this)
        //         .setTitle("温馨提示(隐私合规示例)")
        //         .setMessage(spannable)
        //         .setPositiveButton("同意", new DialogInterface.OnClickListener() {
        //             @Override
        //             public void onClick(DialogInterface dialogInterface, int i) {
        //                 MapsInitializer.updatePrivacyAgree(MainActivity.this,true);
        //             }
        //         })
        //         .setNegativeButton("不同意", new DialogInterface.OnClickListener() {
        //             @Override
        //             public void onClick(DialogInterface dialogInterface, int i) {
        //                 MapsInitializer.updatePrivacyAgree(MainActivity.this,false);
        //             }
        //         })
        //         .show();
    }


    /**
     * 在主线程中提示
     * @param toastMsg 消息
     */
    private void showToast(final String toastMsg) {
        runOnUiThread(() -> Toast.makeText(getApplicationContext(), toastMsg, Toast.LENGTH_SHORT).show());
    }
}